#include "network_protocol.h"
#include "../parser/sql_parser.h"
#include "../executor/executor.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/select.h>
#include <sys/time.h>
#include <arpa/inet.h>

// Default configuration
#define DEFAULT_MAX_CONNECTIONS  1000
#define DEFAULT_THREAD_COUNT     8
#define DEFAULT_READ_BUFFER_SIZE (64 * 1024)   // 64KB
#define DEFAULT_WRITE_BUFFER_SIZE (64 * 1024)  // 64KB
#define CONNECTION_TIMEOUT       300           // 5 minutes

// Server Management Functions

network_server_t* network_server_create(uint16_t port, gudb* database) {
    if (!database) return NULL;
    
    network_server_t* server = malloc(sizeof(network_server_t));
    if (!server) return NULL;
    
    memset(server, 0, sizeof(network_server_t));
    
    // Initialize server configuration
    server->port = port;
    server->database = database;
    server->max_connections = DEFAULT_MAX_CONNECTIONS;
    server->thread_count = DEFAULT_THREAD_COUNT;
    server->read_buffer_size = DEFAULT_READ_BUFFER_SIZE;
    server->write_buffer_size = DEFAULT_WRITE_BUFFER_SIZE;
    server->running = false;
    server->next_connection_id = 1;
    
    // Initialize mutexes
    if (pthread_mutex_init(&server->connection_mutex, NULL) != 0 ||
        pthread_mutex_init(&server->stats_mutex, NULL) != 0 ||
        pthread_cond_init(&server->connection_cond, NULL) != 0) {
        free(server);
        return NULL;
    }
    
    return server;
}

void network_server_destroy(network_server_t* server) {
    if (!server) return;
    
    // Stop server if running
    if (server->running) {
        network_server_stop(server);
    }
    
    // Clean up worker threads
    if (server->worker_threads) {
        free(server->worker_threads);
    }
    
    // Clean up connections
    mysql_connection_t* conn = server->connections;
    while (conn) {
        mysql_connection_t* next = conn->next;
        mysql_connection_destroy(conn);
        conn = next;
    }
    
    // Clean up mutexes
    pthread_mutex_destroy(&server->connection_mutex);
    pthread_mutex_destroy(&server->stats_mutex);
    pthread_cond_destroy(&server->connection_cond);
    
    // Close listen socket
    if (server->listen_sockfd >= 0) {
        close(server->listen_sockfd);
    }
    
    free(server);
}

int network_server_start(network_server_t* server) {
    if (!server || server->running) return -1;
    
    // Create listen socket
    server->listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (server->listen_sockfd < 0) {
        perror("socket");
        return -1;
    }
    
    // Set socket options
    int opt = 1;
    if (setsockopt(server->listen_sockfd, SOL_SOCKET, SO_REUSEADDR, 
                   &opt, sizeof(opt)) < 0) {
        perror("setsockopt");
        close(server->listen_sockfd);
        return -1;
    }
    
    // Bind socket
    memset(&server->server_addr, 0, sizeof(server->server_addr));
    server->server_addr.sin_family = AF_INET;
    server->server_addr.sin_addr.s_addr = INADDR_ANY;
    server->server_addr.sin_port = htons(server->port);
    
    if (bind(server->listen_sockfd, (struct sockaddr*)&server->server_addr, 
             sizeof(server->server_addr)) < 0) {
        perror("bind");
        close(server->listen_sockfd);
        return -1;
    }
    
    // Start listening
    if (listen(server->listen_sockfd, 128) < 0) {
        perror("listen");
        close(server->listen_sockfd);
        return -1;
    }
    
    // Create worker threads
    server->worker_threads = malloc(server->thread_count * sizeof(pthread_t));
    if (!server->worker_threads) {
        close(server->listen_sockfd);
        return -1;
    }
    
    server->running = true;
    
    // Start worker threads
    for (uint32_t i = 0; i < server->thread_count; i++) {
        if (pthread_create(&server->worker_threads[i], NULL, 
                          network_server_worker_thread, server) != 0) {
            server->running = false;
            // Clean up already created threads
            for (uint32_t j = 0; j < i; j++) {
                pthread_cancel(server->worker_threads[j]);
                pthread_join(server->worker_threads[j], NULL);
            }
            free(server->worker_threads);
            server->worker_threads = NULL;
            close(server->listen_sockfd);
            return -1;
        }
    }
    
    // Start main accept thread
    if (pthread_create(&server->accept_thread, NULL, 
                      network_server_accept_thread, server) != 0) {
        server->running = false;
        for (uint32_t i = 0; i < server->thread_count; i++) {
            pthread_cancel(server->worker_threads[i]);
            pthread_join(server->worker_threads[i], NULL);
        }
        free(server->worker_threads);
        server->worker_threads = NULL;
        close(server->listen_sockfd);
        return -1;
    }
    
    printf("GuDB MySQL server listening on port %d\n", server->port);
    return 0;
}

int network_server_stop(network_server_t* server) {
    if (!server || !server->running) return -1;
    
    server->running = false;
    
    // Signal worker threads to stop
    pthread_mutex_lock(&server->connection_mutex);
    pthread_cond_broadcast(&server->connection_cond);
    pthread_mutex_unlock(&server->connection_mutex);
    
    // Wait for accept thread to finish
    pthread_join(server->accept_thread, NULL);
    
    // Wait for worker threads to finish
    if (server->worker_threads) {
        for (uint32_t i = 0; i < server->thread_count; i++) {
            pthread_join(server->worker_threads[i], NULL);
        }
        free(server->worker_threads);
        server->worker_threads = NULL;
    }
    
    // Close listen socket
    if (server->listen_sockfd >= 0) {
        close(server->listen_sockfd);
        server->listen_sockfd = -1;
    }
    
    // Close all connections
    pthread_mutex_lock(&server->connection_mutex);
    mysql_connection_t* conn = server->connections;
    while (conn) {
        mysql_connection_t* next = conn->next;
        if (conn->sockfd >= 0) {
            close(conn->sockfd);
        }
        mysql_connection_destroy(conn);
        conn = next;
    }
    server->connections = NULL;
    server->connection_count = 0;
    pthread_mutex_unlock(&server->connection_mutex);
    
    printf("GuDB MySQL server stopped\n");
    return 0;
}

int network_server_accept_connections(network_server_t* server) {
    if (!server || !server->running) return -1;
    
    while (server->running) {
        struct sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        
        // Accept connection
        int client_sockfd = accept(server->listen_sockfd, 
                                  (struct sockaddr*)&client_addr, 
                                  &client_addr_len);
        
        if (client_sockfd < 0) {
            if (errno == EINTR && !server->running) {
                break;
            }
            perror("accept");
            continue;
        }
        
        // Check connection limit
        pthread_mutex_lock(&server->connection_mutex);
        if (server->connection_count >= server->max_connections) {
            pthread_mutex_unlock(&server->connection_mutex);
            close(client_sockfd);
            
            pthread_mutex_lock(&server->stats_mutex);
            server->aborted_connects++;
            pthread_mutex_unlock(&server->stats_mutex);
            continue;
        }
        pthread_mutex_unlock(&server->connection_mutex);
        
        // Create connection
        mysql_connection_t* conn = mysql_connection_create(client_sockfd, &client_addr);
        if (!conn) {
            close(client_sockfd);
            continue;
        }
        
        // Set server reference
        conn->server_ref = server;
        
        // Initialize buffers
        if (mysql_connection_init_buffers(conn, server->read_buffer_size, 
                                         server->write_buffer_size) != 0) {
            mysql_connection_destroy(conn);
            continue;
        }
        
        // Assign connection ID
        pthread_mutex_lock(&server->connection_mutex);
        conn->connection_id = server->next_connection_id++;
        
        // Add to connection list
        conn->next = server->connections;
        if (server->connections) {
            server->connections->prev = conn;
        }
        server->connections = conn;
        server->connection_count++;
        server->current_connections++;
        server->total_connections++;
        
        if (server->current_connections > server->max_used_connections) {
            server->max_used_connections = server->current_connections;
        }
        
        // Signal worker threads
        pthread_cond_signal(&server->connection_cond);
        pthread_mutex_unlock(&server->connection_mutex);
        
        printf("New connection from %s:%d (ID: %u)\n", 
               inet_ntoa(client_addr.sin_addr), 
               ntohs(client_addr.sin_port),
               conn->connection_id);
    }
    
    return 0;
}

void* network_server_worker_thread(void* arg) {
    network_server_t* server = (network_server_t*)arg;
    if (!server) return NULL;
    
    while (server->running) {
        mysql_connection_t* conn = NULL;
        
        // Wait for a connection to handle
        pthread_mutex_lock(&server->connection_mutex);
        while (server->running && !server->connections) {
            pthread_cond_wait(&server->connection_cond, &server->connection_mutex);
        }
        
        if (!server->running) {
            pthread_mutex_unlock(&server->connection_mutex);
            break;
        }
        
        // Get a connection that needs handling
        conn = server->connections;
        if (conn && conn->state == CONN_STATE_INIT) {
            // Remove from list temporarily
            if (conn->next) {
                conn->next->prev = conn->prev;
            }
            if (conn->prev) {
                conn->prev->next = conn->next;
            } else {
                server->connections = conn->next;
            }
            server->connection_count--;
        } else {
            conn = NULL;
        }
        
        pthread_mutex_unlock(&server->connection_mutex);
        
        if (conn) {
            // Handle connection
            mysql_connection_handler(conn);
            
            // Update statistics
            pthread_mutex_lock(&server->stats_mutex);
            server->current_connections--;
            pthread_mutex_unlock(&server->stats_mutex);
            
            // Clean up connection
            mysql_connection_destroy(conn);
        }
    }
    
    return NULL;
}

void* mysql_connection_handler(void* arg) {
    mysql_connection_t* conn = (mysql_connection_t*)arg;
    if (!conn) return NULL;
    
    // Send initial handshake
    if (mysql_send_handshake(conn) != 0) {
        return NULL;
    }
    
    // Handle handshake response
    mysql_handshake_response_t response;
    memset(&response, 0, sizeof(response));
    
    if (mysql_recv_handshake_response(conn, &response) != 0) {
        mysql_send_error(conn, ER_HANDSHAKE_ERROR, "08S01", 
                        "Bad handshake response");
        return NULL;
    }
    
    // Authenticate user
    if (mysql_authenticate_user(conn, response.username, 
                               response.auth_response, response.database) != 0) {
        mysql_send_error(conn, ER_ACCESS_DENIED_ERROR, "28000", 
                        "Access denied for user");
        return NULL;
    }
    
    // Send OK packet for successful authentication
    mysql_send_ok(conn, 0, 0);
    conn->state = CONN_STATE_COMMAND_READY;
    
    // Main command loop
    while (conn->state != CONN_STATE_CLOSING && conn->state != CONN_STATE_CLOSED) {
        mysql_packet_t* packet = mysql_recv_packet(conn);
        if (!packet) {
            break;
        }
        
        // Parse command
        if (packet->length == 0) {
            mysql_packet_destroy(packet);
            break;
        }
        
        mysql_command_t command = (mysql_command_t)packet->payload[0];
        uint8_t* payload = packet->payload + 1;
        uint32_t payload_length = packet->length - 1;
        
        // Update activity time
        conn->last_activity = time(NULL);
        
        // Handle command
        int result = mysql_handle_command(conn, command, payload, payload_length);
        
        mysql_packet_destroy(packet);
        
        if (result != 0) {
            break;
        }
        
        // Check for quit command
        if (command == COM_QUIT) {
            conn->state = CONN_STATE_CLOSING;
            break;
        }
    }
    
    return NULL;
}

void* network_server_accept_thread(void* arg) {
    network_server_t* server = (network_server_t*)arg;
    if (!server) return NULL;
    
    // Run the accept connections loop
    network_server_accept_connections(server);
    
    return NULL;
}

// Command Handling Functions

int mysql_handle_command(mysql_connection_t* conn, mysql_command_t command, 
                        const uint8_t* payload, uint32_t length) {
    if (!conn) return -1;
    
    conn->queries_executed++;
    
    switch (command) {
        case COM_QUIT:
            return mysql_handle_com_quit(conn);
            
        case COM_INIT_DB: {
            if (length == 0) {
                mysql_send_error(conn, ER_NO_DB_ERROR, "3D000", "No database specified");
                return -1;
            }
            char* database = malloc(length + 1);
            if (!database) {
                mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Memory allocation error");
                return -1;
            }
            memcpy(database, payload, length);
            database[length] = '\0';
            
            int result = mysql_handle_com_init_db(conn, database);
            free(database);
            return result;
        }
        
        case COM_QUERY: {
            if (length == 0) {
                mysql_send_error(conn, ER_SYNTAX_ERROR, "42000", "Empty query");
                return -1;
            }
            char* query = malloc(length + 1);
            if (!query) {
                mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Memory allocation error");
                return -1;
            }
            memcpy(query, payload, length);
            query[length] = '\0';
            
            int result = mysql_handle_query(conn, query);
            free(query);
            return result;
        }
        
        case COM_PING:
            return mysql_handle_com_ping(conn);
            
        case COM_STATISTICS:
            return mysql_handle_com_statistics(conn);
            
        case COM_PROCESS_INFO:
            return mysql_handle_com_process_info(conn);
            
        default:
            mysql_send_error(conn, ER_UNKNOWN_COM_ERROR, "08S01", 
                           "Unknown command");
            return -1;
    }
}

int mysql_handle_com_quit(mysql_connection_t* conn) {
    if (!conn) return -1;
    
    conn->state = CONN_STATE_CLOSING;
    return 0;
}

int mysql_handle_com_init_db(mysql_connection_t* conn, const char* database) {
    if (!conn || !database) return -1;
    
    // Update connection database
    strncpy(conn->database, database, sizeof(conn->database) - 1);
    conn->database[sizeof(conn->database) - 1] = '\0';
    
    mysql_send_ok(conn, 0, 0);
    return 0;
}

int mysql_handle_com_ping(mysql_connection_t* conn) {
    if (!conn) return -1;
    
    mysql_send_ok(conn, 0, 0);
    return 0;
}

int mysql_handle_com_statistics(mysql_connection_t* conn) {
    if (!conn) return -1;
    
    // Create statistics string
    char stats[512];
    time_t uptime = time(NULL) - conn->connect_time;
    
    snprintf(stats, sizeof(stats),
             "Uptime: %ld  Threads: 1  Questions: %llu  Queries per second avg: %.3f",
             uptime, conn->queries_executed, 
             uptime > 0 ? (double)conn->queries_executed / uptime : 0.0);
    
    size_t stats_len = strlen(stats);
    mysql_packet_t* packet = mysql_packet_create(stats_len, conn->sequence_id);
    if (!packet) {
        mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Memory allocation error");
        return -1;
    }
    
    memcpy(packet->payload, stats, stats_len);
    
    int result = mysql_send_packet(conn, packet);
    mysql_packet_destroy(packet);
    
    return result;
}

int mysql_handle_com_process_info(mysql_connection_t* conn) {
    if (!conn) return -1;
    
    // Create a simple result set with process information
    mysql_result_set_t* result = mysql_result_set_create(8);
    if (!result) {
        mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Memory allocation error");
        return -1;
    }
    
    // Add field definitions
    mysql_result_set_add_field(result, 0, "Id", MYSQL_TYPE_LONG, 10);
    mysql_result_set_add_field(result, 1, "User", MYSQL_TYPE_VAR_STRING, 64);
    mysql_result_set_add_field(result, 2, "Host", MYSQL_TYPE_VAR_STRING, 64);
    mysql_result_set_add_field(result, 3, "db", MYSQL_TYPE_VAR_STRING, 64);
    mysql_result_set_add_field(result, 4, "Command", MYSQL_TYPE_VAR_STRING, 16);
    mysql_result_set_add_field(result, 5, "Time", MYSQL_TYPE_LONG, 10);
    mysql_result_set_add_field(result, 6, "State", MYSQL_TYPE_VAR_STRING, 64);
    mysql_result_set_add_field(result, 7, "Info", MYSQL_TYPE_VAR_STRING, 512);
    
    // Add current connection as a row
    char* row_data[8];
    char id_str[32], time_str[32];
    
    snprintf(id_str, sizeof(id_str), "%u", conn->connection_id);
    snprintf(time_str, sizeof(time_str), "%ld", time(NULL) - conn->connect_time);
    
    row_data[0] = id_str;
    row_data[1] = conn->username[0] ? conn->username : "unknown";
    row_data[2] = inet_ntoa(conn->client_addr.sin_addr);
    row_data[3] = conn->database[0] ? conn->database : NULL;
    row_data[4] = "Sleep";
    row_data[5] = time_str;
    row_data[6] = "";
    row_data[7] = NULL;
    
    uint64_t lengths[8] = {
        strlen(row_data[0]),
        strlen(row_data[1]),
        strlen(row_data[2]),
        row_data[3] ? strlen(row_data[3]) : 0,
        strlen(row_data[4]),
        strlen(row_data[5]),
        strlen(row_data[6]),
        0
    };
    
    mysql_result_set_add_row(result, row_data, lengths);
    
    int ret = mysql_send_result_set(conn, result);
    mysql_result_set_destroy(result);
    
    return ret;
}

// Query Handling (Basic Implementation)

int mysql_handle_query(mysql_connection_t* conn, const char* query) {
    if (!conn || !query) return -1;
    
    conn->state = CONN_STATE_QUERY_EXECUTING;
    
    // Get the database server reference (we need to properly initialize this)
    network_server_t* server = (network_server_t*)conn->server_ref;
    if (!server || !server->database) {
        mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Database not available");
        conn->state = CONN_STATE_COMMAND_READY;
        return -1;
    }
    
    // Handle special MySQL compatibility queries first
    if (strncasecmp(query, "SELECT @@version_comment", 24) == 0) {
        mysql_result_set_t* result = mysql_result_set_create(1);
        if (!result) {
            mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Memory allocation error");
            return -1;
        }
        
        mysql_result_set_add_field(result, 0, "@@version_comment", MYSQL_TYPE_VAR_STRING, 64);
        
        char* row_data[1] = {"GuDB Database Server"};
        uint64_t lengths[1] = {20};
        mysql_result_set_add_row(result, row_data, lengths);
        
        int ret = mysql_send_result_set(conn, result);
        mysql_result_set_destroy(result);
        
        conn->state = CONN_STATE_COMMAND_READY;
        return ret;
    }
    else if (strncasecmp(query, "SHOW DATABASES", 14) == 0) {
        mysql_result_set_t* result = mysql_result_set_create(1);
        if (!result) {
            mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Memory allocation error");
            return -1;
        }
        
        mysql_result_set_add_field(result, 0, "Database", MYSQL_TYPE_VAR_STRING, 64);
        
        char* row_data[1] = {"gudb"};
        uint64_t lengths[1] = {4};
        mysql_result_set_add_row(result, row_data, lengths);
        
        int ret = mysql_send_result_set(conn, result);
        mysql_result_set_destroy(result);
        
        conn->state = CONN_STATE_COMMAND_READY;
        return ret;
    }
    else {
        // Create or use existing transaction
        gudb_txn* txn = conn->current_txn;
        bool created_txn = false;
        
        if (!txn) {
            txn = gudb_begin(server->database, GU_TXN_RC, conn->database[0] ? conn->database : "gudb");
            if (!txn) {
                mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Failed to create transaction");
                conn->state = CONN_STATE_COMMAND_READY;
                return -1;
            }
            created_txn = true;
            
            if (!conn->in_transaction) {
                conn->current_txn = txn;
            }
        }
        
        // Execute the SQL query using GuDB's SQL execution engine
        result_t* gudb_result = NULL;
        int exec_result = gudb_exec(txn, query, NULL, &gudb_result);
        
        if (exec_result != GU_OK) {
            // Handle SQL execution error
            const char* error_msg = "SQL execution failed";
            switch (exec_result) {
                case GU_ERR_SYNTAX:
                    error_msg = "Syntax error in SQL statement";
                    break;
                case GU_ERR_NOMEM:
                    error_msg = "Out of memory";
                    break;
                case GU_ERR_IO:
                    error_msg = "I/O error";
                    break;
                default:
                    error_msg = "Unknown error";
                    break;
            }
            
            mysql_send_error(conn, ER_SYNTAX_ERROR, "42000", error_msg);
            
            if (created_txn) {
                gudb_rollback(txn);
                if (conn->current_txn == txn) {
                    conn->current_txn = NULL;
                }
            }
            
            conn->state = CONN_STATE_COMMAND_READY;
            return -1;
        }
        
        // Convert GuDB result to MySQL result set
        if (gudb_result && gudb_result->col_count > 0) {
            // This is a query that returns data (SELECT)
            mysql_result_set_t* mysql_result = mysql_result_set_create(gudb_result->col_count);
            if (!mysql_result) {
                mysql_send_error(conn, ER_UNKNOWN_ERROR, "HY000", "Memory allocation error");
                gudb_free_result(gudb_result);
                
                if (created_txn) {
                    gudb_rollback(txn);
                    if (conn->current_txn == txn) {
                        conn->current_txn = NULL;
                    }
                }
                
                conn->state = CONN_STATE_COMMAND_READY;
                return -1;
            }
            
            // Add field definitions
            for (uint32_t i = 0; i < gudb_result->col_count; i++) {
                const char* col_name = (gudb_result->column_names && gudb_result->column_names[i]) 
                                     ? gudb_result->column_names[i] : "unknown";
                mysql_result_set_add_field(mysql_result, i, col_name, MYSQL_TYPE_VAR_STRING, 255);
            }
            
            // Add data rows
            if (gudb_result->rows && gudb_result->row_count > 0) {
                for (uint32_t row = 0; row < gudb_result->row_count; row++) {
                    if (gudb_result->rows[row]) {
                        uint64_t* lengths = malloc(gudb_result->col_count * sizeof(uint64_t));
                        if (lengths) {
                            for (uint32_t col = 0; col < gudb_result->col_count; col++) {
                                lengths[col] = gudb_result->rows[row][col] 
                                             ? strlen(gudb_result->rows[row][col]) : 0;
                            }
                            mysql_result_set_add_row(mysql_result, gudb_result->rows[row], lengths);
                            free(lengths);
                        }
                    }
                }
            }
            
            int ret = mysql_send_result_set(conn, mysql_result);
            mysql_result_set_destroy(mysql_result);
            gudb_free_result(gudb_result);
            
            // Commit transaction if we created it and not in explicit transaction
            if (created_txn && conn->autocommit) {
                gudb_commit(txn);
                if (conn->current_txn == txn) {
                    conn->current_txn = NULL;
                }
            }
            
            conn->state = CONN_STATE_COMMAND_READY;
            return ret;
        }
        else {
            // This is a statement that doesn't return data (INSERT, UPDATE, DELETE)
            uint64_t affected_rows = (exec_result >= 0) ? exec_result : 0;
            mysql_send_ok(conn, affected_rows, 0);
            
            if (gudb_result) {
                gudb_free_result(gudb_result);
            }
            
            // Commit transaction if we created it and not in explicit transaction
            if (created_txn && conn->autocommit) {
                gudb_commit(txn);
                if (conn->current_txn == txn) {
                    conn->current_txn = NULL;
                }
            }
            
            conn->state = CONN_STATE_COMMAND_READY;
            return 0;
        }
    }
}

// Configuration Functions

int network_server_set_max_connections(network_server_t* server, uint32_t max_connections) {
    if (!server) return -1;
    
    pthread_mutex_lock(&server->connection_mutex);
    server->max_connections = max_connections;
    pthread_mutex_unlock(&server->connection_mutex);
    
    return 0;
}

int network_server_set_buffer_sizes(network_server_t* server, size_t read_size, size_t write_size) {
    if (!server) return -1;
    
    server->read_buffer_size = read_size;
    server->write_buffer_size = write_size;
    
    return 0;
}

int network_server_set_thread_count(network_server_t* server, uint32_t thread_count) {
    if (!server || server->running) return -1;
    
    server->thread_count = thread_count;
    return 0;
}

// Statistics Functions

void network_server_print_stats(network_server_t* server) {
    if (!server) return;
    
    pthread_mutex_lock(&server->stats_mutex);
    
    printf("Network Server Statistics:\n");
    printf("  Port: %u\n", server->port);
    printf("  Running: %s\n", server->running ? "Yes" : "No");
    printf("  Total connections: %llu\n", server->total_connections);
    printf("  Current connections: %llu\n", server->current_connections);
    printf("  Max used connections: %llu\n", server->max_used_connections);
    printf("  Max connections: %u\n", server->max_connections);
    printf("  Aborted connects: %llu\n", server->aborted_connects);
    printf("  Aborted clients: %llu\n", server->aborted_clients);
    printf("  Thread count: %u\n", server->thread_count);
    printf("  Read buffer size: %zu bytes\n", server->read_buffer_size);
    printf("  Write buffer size: %zu bytes\n", server->write_buffer_size);
    
    pthread_mutex_unlock(&server->stats_mutex);
}

uint32_t network_server_get_connection_count(network_server_t* server) {
    if (!server) return 0;
    
    pthread_mutex_lock(&server->connection_mutex);
    uint32_t count = server->connection_count;
    pthread_mutex_unlock(&server->connection_mutex);
    
    return count;
}